home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / game / shoot / ADescentSrc.lha / descent / 2d / gr.c < prev    next >
C/C++ Source or Header  |  1999-03-18  |  24KB  |  1,062 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: /usr/CVS/descent/2d/gr.c,v $
  15.  * $Revision: 1.20 $
  16.  * $Author: nobody $
  17.  * $Date: 1999/03/10 23:26:38 $
  18.  *
  19.  * Graphical routines for setting video modes, etc.
  20.  *
  21.  * $Log: gr.c,v $
  22.  * Revision 1.20  1999/03/10 23:26:38  nobody
  23.  * Warp3D V2 adaption
  24.  *
  25.  * Revision 1.19  1998/12/21 17:11:13  nobody
  26.  * *** empty log message ***
  27.  *
  28.  * Revision 1.18  1998/11/09 22:20:09  nobody
  29.  * *** empty log message ***
  30.  *
  31.  * Revision 1.17  1998/09/26 15:03:51  nobody
  32.  * Added Warp3D support
  33.  *
  34.  * Revision 1.16  1998/08/11 14:38:35  nobody
  35.  * Conflicts ?
  36.  *
  37.  * Revision 1.15  1998/05/13 14:57:37  hfrieden
  38.  * *** empty log message ***
  39.  *
  40.  * Revision 1.14  1998/04/24 14:18:02  tfrieden
  41.  * Unsuccesful try for a cgx wbmode kludge
  42.  *
  43.  * Revision 1.13  1998/04/05 13:30:24  tfrieden
  44.  * Some changes in screen mode request, and wbmode
  45.  *
  46.  * Revision 1.12  1998/04/05 01:52:25  tfrieden
  47.  * Added ECS support
  48.  *
  49.  * Revision 1.11  1998/04/03 13:58:49  tfrieden
  50.  * Exeprimental Workbench support
  51.  *
  52.  * Revision 1.10  1998/03/31 17:03:38  hfrieden
  53.  * Removed placement bug with ViRGE version
  54.  *
  55.  * Revision 1.9  1998/03/30 18:39:14  hfrieden
  56.  * Conflicts removed
  57.  *
  58.  * Revision 1.8  1998/03/30 12:33:38  tfrieden
  59.  * Corrected the SM_ORIGINAL bug
  60.  *
  61.  * Revision 1.7  1998/03/28 23:04:15  tfrieden
  62.  * Remove OpenLibrary stuff
  63.  *
  64.  * Revision 1.6  1998/03/25 21:55:51  tfrieden
  65.  * Some more errors corrected (register spills)
  66.  *
  67.  * Revision 1.5  1998/03/23 20:08:29  hfrieden
  68.  * Added Workbench info window
  69.  *
  70.  * Revision 1.4  1998/03/22 15:48:50  hfrieden
  71.  * ViRGE stuff fixed
  72.  *
  73.  * Revision 1.3  1998/03/18 23:19:26  tfrieden
  74.  * Added support for cybergraphics direct access
  75.  *
  76.  * Revision 1.2  1998/03/14 13:55:23  hfrieden
  77.  * Preliminary ViRGE support added
  78.  *
  79.  * Revision 1.3  1998/02/28 01:13:03  tfrieden
  80.  * Additional AGA stuff
  81.  *
  82.  * Revision 1.2  1998/02/22 13:25:22  tfrieden
  83.  * Added mouse pointer stuff
  84.  *
  85.  * Revision 1.1.1.1  1998/02/13  20:21:22  hfrieden
  86.  * Initial Import
  87.  */
  88.  
  89. #include <stdlib.h>
  90. #include <stdio.h>
  91. #include <string.h>
  92. #include <cybergraphx/cybergraphics.h>
  93. #include <inline/cybergraphics.h>
  94. #include <inline/intuition.h>
  95. #include <intuition/intuition.h>
  96. #include <inline/graphics.h>
  97. #include <graphics/gfx.h>
  98. #include <graphics/displayinfo.h>
  99. #include <inline/exec.h>
  100. #include <exec/exec.h>
  101. #include <clib/asl_protos.h>
  102. #include <libraries/asl.h>
  103. #include <inline/asl.h>
  104. #include "c2p_040.h"
  105.  
  106. #ifdef VIRGIN
  107. #include <cybergraphics/cgx3dvirgin.h>
  108. #include <clib/cgx3dvirgin_protos.h>
  109. #include <inline/cgx3dvirgin.h>
  110. #include "VirgeTexture.h"
  111. #endif
  112.  
  113. #ifdef WARP3D
  114. #include <Warp3D/Warp3D.h>
  115. #include <clib/Warp3D_protos.h>
  116. #include <inline/Warp3D.h>
  117. #endif
  118.  
  119. #include "types.h"
  120. #include "mem.h"
  121. #include "gr.h"
  122. #include "grdef.h"
  123. #include "error.h"
  124. #include "mono.h"
  125. #include "palette.h"
  126. #include "args.h"
  127.  
  128. #define debug(x) // printf x
  129.  
  130. extern unsigned short gr_bitvalues[];
  131. extern int VR_screen_mode;
  132.  
  133. char gr_pal_default[768];
  134.  
  135. ULONG gr_pixfmt = 0;
  136. int gr_installed = 0;
  137. int gr_mouse_reported = 0;
  138. int gr_keep_resolution = 0;
  139.  
  140. int gr_show_screen_info = 0;
  141. double wscale = 1.0;
  142. double hscale = 1.0;
  143. //  Amiga system stuff
  144. #ifdef VIRGIN
  145. extern struct Library *CGX3DVirginBase;
  146. View3D MyView;
  147. struct MsgPort *MyViewMsgPort;
  148. ULONG BufNum = 0;
  149. ULONG virgin_depth = 15;
  150. int VirgeHave320 = 0;
  151. #endif
  152.  
  153. #ifdef WARP3D
  154. extern W3D_Context *WARP_Context;
  155. extern struct Library *Warp3DBase;
  156. extern int WARP_Buffer;
  157. #endif
  158.  
  159. #ifndef VIRGIN
  160. struct Screen *scr = NULL;
  161. struct Window *win = NULL;
  162.  
  163. struct ScreenBuffer *sb1 = NULL, *sb2 = NULL;
  164. #endif
  165.  
  166. extern struct Library *CyberGfxBase;
  167. extern struct Library *IntuitionBase;
  168. extern struct Library *GfxBase;
  169. extern struct Library *AslBase;
  170. extern struct Library *SysBase;
  171. struct BitMap *tmp = NULL;
  172. struct BitMap bm;
  173. struct RastPort TempRas;
  174. struct Window *InfoWin = 0;
  175. struct Screen *InfoScr = 0;
  176. UBYTE *OffscreenBuffer = NULL;
  177. int OffscreenW = 0, OffscreenH = 0;
  178. int OffscreenSize = 0;
  179. char ScreenType = 1;    // 0 = AGA, 1 = CyberGfx, 2 = EHB
  180. int depth = 8;
  181. int cgx_direct;
  182. PLANEPTR planes = NULL;
  183. UBYTE *compare_buffer = NULL;
  184.  
  185. struct ScreenModeRequester *smr;
  186.  
  187. UWORD *PointerData = NULL;
  188.  
  189. UWORD  EditorPointer[]  = {
  190.     0x0000, 0x0000,
  191.  
  192.     0xc000, 0x0000,
  193.     0xf000, 0x0000,
  194.     0x7c00, 0x0000,
  195.     0x7f00, 0x0000,
  196.     0x3fc0, 0x0000,
  197.     0x3fc0, 0x0000,
  198.     0x1f00, 0x0000,
  199.     0x1f80, 0x0000,
  200.     0x0dc0, 0x0000,
  201.     0x0ce0, 0x0000,
  202.     0x0060, 0x0000,
  203.  
  204.     0x0000, 0x0000
  205. };
  206.  
  207.  
  208. // Variables for screenmodes
  209. unsigned long Mode320x200;
  210. unsigned long Mode320x400;
  211. unsigned long Mode640x480;
  212. unsigned long Mode800x600;
  213. int farg;
  214. int wbmode = 0;
  215. short wbmode_cgxkludge = 0;
  216.  
  217. // Pallette stuff
  218. long wbpal[256*3+2];
  219. UBYTE xlate[256];
  220. short palette_changed;
  221. extern ULONG palette[];
  222. char *gr_sc_small = "Small Screen";
  223. char *gr_sc_medium = "Medium Screen";
  224. char *gr_sc_large = "Large Screen";
  225.  
  226. void gr_wlpa(void);
  227.  
  228. #ifdef VIRGIN
  229. char *InfoTxt = "Loading ViRGE ADescent";
  230. #elif defined(WARP3D)
  231. char *InfoTxt = "Loading Warp3D ADescent";
  232. #else
  233. char *InfoTxt = "Loading ADescent";
  234. #endif
  235.  
  236. void HideInfoWindow(void)
  237. {
  238.     if (InfoWin) CloseWindow(InfoWin);
  239.     InfoWin = 0;
  240. }
  241.  
  242. void ShowInfoWindow(void)
  243. {
  244.     ULONG w,h;
  245.     ULONG b,l;
  246.     struct DrawInfo *dri;
  247.  
  248.     atexit(HideInfoWindow);
  249.  
  250.     InfoScr = LockPubScreen(NULL);
  251.     if (!InfoScr) goto siw_fail;
  252.  
  253.     dri = GetScreenDrawInfo(InfoScr);
  254.     if (!dri) {
  255.         UnlockPubScreen(NULL, InfoScr);
  256.         InfoScr = 0;
  257.         goto siw_fail;
  258.     }
  259.  
  260.     w = (ULONG)InfoScr->Width;
  261.     h = (ULONG)InfoScr->Height;
  262.     b = (ULONG)(dri->dri_Font->tf_YSize);
  263.  
  264.     InfoWin = OpenWindowTags(NULL,
  265.         WA_InnerHeight,         b+8,
  266.         WA_InnerWidth,          w/2,
  267.         WA_Left,                w/4,
  268.         WA_Top,                 (h/2)-b,
  269.         WA_CloseGadget,         FALSE,
  270.         WA_DragBar,             FALSE,
  271.         WA_SizeGadget,          FALSE,
  272.         WA_DepthGadget,         FALSE,
  273.         WA_Activate,            TRUE,
  274.     TAG_DONE);
  275.  
  276.     if (InfoWin) {
  277.         SetAPen(InfoWin->RPort, dri->dri_Pens[TEXTPEN]);
  278.         SetFont(InfoWin->RPort, dri->dri_Font);
  279.         l = TextLength(InfoWin->RPort, InfoTxt, strlen(InfoTxt));
  280.         Move(InfoWin->RPort, w/4-l/2, InfoWin->BorderTop+dri->dri_Font->tf_Baseline+2);
  281.         Text(InfoWin->RPort, InfoTxt, strlen(InfoTxt));
  282.     }
  283.  
  284.     FreeScreenDrawInfo(InfoScr, dri);
  285.     UnlockPubScreen(NULL, InfoScr);
  286. siw_fail:
  287. }
  288.  
  289.  
  290. #ifdef VIRGIN
  291. void gccWriteRect(int dummy, ...)
  292. {
  293.     V3D_WriteRect(OffscreenBuffer, 0,0, OffscreenW, MyView, 0,0,
  294.         OffscreenW, OffscreenH, RECT2D_LUT8);
  295. }
  296. #endif
  297.  
  298. void gr_update2(void)
  299. {
  300. #ifndef VIRGIN
  301.     if (ScreenType == 1) {
  302.         WritePixelArray(OffscreenBuffer, 0, 0, OffscreenW, win->RPort, 0, 0, OffscreenW-1,
  303.                 OffscreenH-1, RECTFMT_LUT8);
  304.     } else if (ScreenType == 0) {
  305.         c2p_8_040((UBYTE *)OffscreenBuffer, planes, compare_buffer, OffscreenSize);
  306.     } else if (ScreenType == 2) {
  307.         c2p_6_040_kludge((UBYTE *)OffscreenBuffer, planes, compare_buffer, xlate, OffscreenSize, palette_changed);
  308.         palette_changed = 0;
  309.     }
  310.  
  311. #else
  312.     //printf("Updating...\n");
  313.     if (V3D_LockView(MyView)) {
  314.         gccWriteRect(0);
  315.         V3D_UnLockView(MyView);
  316.     #ifdef VIRGIN_DBUF
  317.         BufNum++; BufNum&=1;
  318.         V3D_FlipBuffer(MyView, (ULONG)BufNum);
  319.     #endif
  320.     }
  321. #endif
  322. }
  323.  
  324. void gr_update3(void)
  325. {
  326. #ifndef VIRGIN
  327. //        WriteLUTPixelArray(OffscreenBuffer, 0, 0, OffscreenW, win->RPort, wbpal,
  328. //                win->BorderLeft, win->BorderTop,
  329. //                OffscreenW-1, OffscreenH-1, CTABFMT_XRGB8);
  330. #endif
  331. }
  332.  
  333. void gr_update(grs_canvas *canv)
  334. {
  335. #ifdef WARP3D
  336.     WARP_Update(win->Height/2*(1-WARP_Buffer));
  337. #else
  338.     if (cgx_direct == 1) return;
  339.     if (wbmode == 0) {
  340.         gr_update2();
  341.     } else
  342.         gr_update3();
  343. #endif
  344. }
  345.  
  346. void gr_close()
  347. {
  348. #ifdef VIRGIN
  349.     extern void VirgeCleanupTextureCache(void);
  350. #endif
  351.  
  352.     printf("Closing graphics subsystem\n");
  353.     gr_set_current_canvas(NULL);
  354.     gr_clear_canvas( BM_XRGB(0,0,0) );
  355.     if (gr_installed==1)
  356.     {
  357.         gr_installed = 0;
  358.         mem_free(grd_curscreen);
  359.     }
  360.  
  361.     if (PointerData)        FreeVec(PointerData);
  362.     if (OffscreenBuffer)    FreeVec(OffscreenBuffer);
  363. #ifdef WARP3D
  364.     WARP_Close();
  365. #endif
  366. #ifdef VIRGIN
  367.     VirgeCleanupTextureCache();
  368.     if (MyView)             V3D_CloseView(MyView);
  369.     VirgePrintTextureStatistics();
  370. #else
  371.  
  372.  
  373.     if (win)                CloseWindow(win);
  374.     if (scr) {
  375.         if (wbmode)
  376.             UnlockPubScreen(NULL, scr);
  377.         else
  378.             CloseScreen(scr);
  379.     }
  380. #endif
  381.     if (planes)             FreeVec(planes);
  382. }
  383.  
  384.  
  385. unsigned long gr_asl_req(int iw, int ih, int mw, int mh, int xw, int xh, char *text)
  386. {
  387. #ifdef WARP3D
  388.     ULONG depth = 15;
  389.     ULONG mdepth = 15;
  390. #else
  391.     ULONG depth = 8;
  392.     ULONG mdepth = 6;
  393. #endif
  394.  
  395.     ULONG mode;
  396.     if (CyberGfxBase) {
  397.         mode = BestCModeIDTags( CYBRBIDTG_NominalWidth,     iw,
  398.                                 CYBRBIDTG_NominalHeight,    ih,
  399.                                 CYBRBIDTG_Depth,            depth,
  400.                                 TAG_DONE);
  401.     } else {
  402.         mode = BestModeID( BIDTAG_NominalWidth,     iw,
  403.                            BIDTAG_NominalHeight,    ih,
  404.                            BIDTAG_Depth,            8,
  405.                            BIDTAG_DIPFMustNotHave,  DIPF_IS_DUALPF|DIPF_IS_PF2PRI|DIPF_IS_HAM,
  406.                            TAG_DONE);
  407.     }
  408.  
  409.     if (AslRequestTags((APTR)smr,
  410.             ASLSM_TitleText,            (ULONG)text,
  411.             ASLSM_InitialDisplayID,     mode,
  412.             ASLSM_MinWidth,             mw,
  413.             ASLSM_MaxWidth,             xw,
  414.             ASLSM_MinHeight,            mh,
  415.             ASLSM_MaxHeight,            xh,
  416.             ASLSM_MinDepth,             mdepth,
  417.             ASLSM_MaxDepth,             depth,
  418.             ASLSM_PropertyMask,         DIPF_IS_DUALPF|DIPF_IS_PF2PRI|DIPF_IS_HAM,
  419.             ASLSM_PropertyFlags,        0,
  420.             TAG_DONE))
  421.             return (unsigned long)smr->sm_DisplayID;
  422.     else
  423.         return(0);
  424. }
  425.  
  426.  
  427. int gr_select_mode(void)
  428. {
  429.  
  430.     smr = AllocAslRequestTags( ASL_ScreenModeRequest,
  431.             ASLSM_PubScreenName,        (ULONG)"Workbench",
  432.             ASLSM_TitleText,            (ULONG)"Select screen mode",
  433.             TAG_DONE);
  434.  
  435.     if (Mode320x200 == 0) {
  436.         Mode320x200 = gr_asl_req(320,200, 320,200, 320,256,
  437.                 "Select 320x200 screenmode (game/menu)");
  438.         if (!Mode320x200) return 0;
  439.     }
  440.  
  441.  
  442.     if (Mode320x400 == 0) {
  443.         Mode320x400 = gr_asl_req(320,400, 320,400, 320,512,
  444.                 "Select 320x400 screenmode (small automap)");
  445.         if (!Mode320x400) return 0;
  446.  
  447.     }
  448.  
  449.     if (Mode640x480 == 0) {
  450.         Mode640x480 = gr_asl_req(640,480, 640,480, 640,512,
  451.                 "Select 640x480 screenmode (large automap/game)");
  452.         if (!Mode640x480) return 0;
  453.     }
  454.     if (Mode800x600 == 0) {
  455.         Mode800x600 = gr_asl_req(800,600, 800, 600, 800,600,
  456.                 "Select 800x600 screenmode (editor)");
  457.         if (!Mode800x600) Mode800x600=Mode640x480;
  458.     }
  459.  
  460.     FreeAslRequest((APTR)smr);
  461.     return 1;
  462. }
  463.  
  464.  
  465. int gr_set_mode(int mode)
  466. {
  467. #ifdef WARP3D
  468.     return WARP_set_mode(mode);
  469. #else
  470.     int w, h, r, x, y;
  471.     ULONG sa_error;
  472.     char *smode;
  473.     int i;
  474.     long cmode;
  475.     ulong adr;
  476.     int direct = 0;
  477.     struct DisplayInfo di_info;
  478.     DisplayInfoHandle di_handle;
  479. #ifndef VIRGIN
  480.     struct Screen *scr2=NULL;
  481.     struct Window *win2=NULL;
  482. #else
  483.     int ww,hh;
  484.     int ModeBackup;
  485.     View3D MyView2 = NULL;
  486.     struct TagItem opentags[] = {
  487.         {V3DVA_UseZBuffer,   FALSE},
  488.         {TAG_DONE,           0}
  489.     };
  490.     extern void VirgeInitTextureCache(void);
  491.  
  492.  
  493. #endif
  494.  
  495.     debug(("gr_set_mode\n"));
  496.     if (gr_keep_resolution && scr) return 0;
  497.  
  498.     if (!PointerData) {
  499.         PointerData = AllocVec(256, MEMF_CLEAR|MEMF_CHIP);
  500.         farg = FindArg("-smr");
  501. #ifndef VIRGIN
  502.         if (CyberGfxBase) {
  503.             wbmode = FindArg("-wbmode"); // Doesn`t work yet
  504.             /*if (wbmode && FindArg("-cgxkludge")) {
  505.                 wbmode_cgxkludge = 1;
  506.             } else {
  507.                 wbmode_cgxkludge = 0;
  508.             } */
  509.         }
  510. #endif
  511.     }
  512.  
  513. #ifndef VIRGIN
  514.     debug(("gr_set_mode: Checking modes\n"));
  515.     if (Mode320x200 == 0 || Mode320x400 == 0 || Mode640x480 == 0 || Mode800x600 == 0 || farg != 0) {
  516.         if (farg != 0) {
  517.             Mode320x200 = 0;
  518.             Mode320x400 = 0;
  519.             Mode640x480 = 0;
  520.             Mode800x600 = 0;
  521.             farg = 0;
  522.         }
  523.         debug(("gr_set_mode: selecting screen modes\n"));
  524.         if (gr_select_mode() == 0) exit(1); //  smr canceled
  525.     }
  526.  
  527. #endif
  528.  
  529. #ifndef VIRGIN
  530.     if (scr) {
  531.         scr2 = scr;
  532.         win2 = win;
  533.         scr=NULL;
  534.     }
  535. #else
  536.     if (MyView) {
  537.         MyView2 = MyView;
  538.         MyView = NULL;
  539.     }
  540.     if (MyViewMsgPort) {
  541.         V3D_DeleteEventPort(MyViewMsgPort);
  542.         MyViewMsgPort = NULL;
  543.     }
  544. #endif
  545.  
  546.     debug(("gr_set_mode: determining parameters\n"));
  547.  
  548.     if (gr_keep_resolution) mode = VR_screen_mode;
  549.     switch (mode) {
  550.         case SM_ORIGINAL:
  551.             return 0;
  552.         case SM_320x200x8:
  553.         case SM_320x200C:
  554.         case SM_320x200x8UL:
  555.             w = 320;
  556.             h = 200;
  557.             smode = gr_sc_small;
  558.             #ifdef VIRGIN
  559.             ww = 320;
  560.             if (VirgeHave320 == 0) {
  561.                 hh = 240;
  562.                 //h  = 240;
  563.             } else {
  564.                 hh = 200;
  565.                 //h  = 200;
  566.             }
  567.             #endif
  568.             x = 0;
  569.             y = 0;
  570.             cmode = Mode320x200;
  571.             break;
  572.         case SM_320x400U:
  573.             w = 320;
  574.             h = 400;
  575.             smode = gr_sc_medium;
  576.             #ifdef VIRGIN
  577.             ww = 320;
  578.             hh = 400;
  579.             #endif
  580.             x = 0;
  581.             y = 0;
  582.             cmode = Mode320x400;
  583.             break;
  584.  
  585.         case SM_320x200x16:
  586.             exit(1);
  587.             break;
  588.         case SM_800x600V:
  589.             w = 800;
  590.             h = 600;
  591.             x = 0;
  592.             y = 0;
  593.             cmode = Mode800x600;
  594.             break;
  595.  
  596.         default:
  597.             printf("Warning: Unknown screen mode. Opening large default\n");
  598.         case SM_640x480V:
  599.             w = 640;
  600.             h = 480;
  601.             smode = gr_sc_large;
  602.             #ifdef VIRGIN
  603.             ww = 640;
  604.             hh = 480;
  605.             #endif
  606.             x = 0;
  607.             y = 0;
  608.             cmode = Mode640x480;
  609.             break;
  610.             
  611.     }
  612.  
  613. #ifndef VIRGIN
  614.  
  615.     GetDisplayInfoData(NULL, (UBYTE *)&di_info, sizeof(di_info), DTAG_DISP, cmode);
  616.     if (di_info.PropertyFlags & DIPF_IS_EXTRAHALFBRITE) {
  617.         depth = 6;
  618.         ScreenType = 2;
  619.     } else {
  620.         depth = 8;
  621.         ScreenType = 0;
  622.         if (CyberGfxBase) {
  623.             if (IsCyberModeID(cmode)) {
  624.                 ScreenType = 1;
  625.                 if (FindArg( "-vdirect" ) && wbmode==0)
  626.                     cgx_direct = 1;
  627.             }
  628.         }
  629.     }
  630.  
  631.  
  632. #ifdef WARP3D
  633.     depth = 15;
  634. #endif
  635.  
  636.     if (scr) {
  637.         scr2 = scr;
  638.         win2 = win;
  639.         scr=NULL;
  640.     }
  641. #else
  642.     if (MyView) {
  643.         MyView2 = MyView;
  644.         MyView = NULL;
  645.     }
  646. #endif
  647.  
  648. #if !defined(VIRGIN) && !defined(WARP3D)
  649.  
  650.     if (planes) FreeVec(planes);
  651.     if (ScreenType == 0 || ScreenType == 2) {
  652.         planes = AllocVec(depth * RASSIZE(w, h), MEMF_CHIP|MEMF_CLEAR); //  Chip ram for AGA
  653.     } else {
  654.         planes = AllocVec(depth * RASSIZE(w, h), MEMF_CLEAR);           //  Other (fast) for CGX
  655.     }
  656.     if (!planes) {
  657.         Error("No memory for display, allocation failed (%d*RASSIZE(%d,%d) = %d)\n",
  658.             depth, w, h, depth*RASSIZE(w,h));
  659.         exit(1);
  660.     }
  661.     InitBitMap(&bm, depth, w, h);
  662.     for (i = 0; i < depth; i++) {
  663.         bm.Planes[i] = planes + i * RASSIZE(w, h);
  664. //        printf("Plane %i @ 0x%08x\n", i, bm.Planes[i]);
  665.     }
  666. #else
  667.     planes = 0;
  668. #endif
  669.  
  670. #ifndef VIRIGN
  671.     if (!scr) {
  672.         if (!wbmode) {
  673. #ifdef WARP3D
  674.     int f = 2;
  675.     debug(("gr_set_mode: Opening screen\n"));
  676.             scr = OpenScreenTags( NULL,
  677.                 SA_Quiet,       TRUE,
  678.                 SA_Left,        0,
  679.                 SA_Top,         0,
  680.                 SA_Width,       w,
  681.                 SA_Height,      h*f,
  682.                 SA_Title,       (ULONG)smode,
  683.                 SA_Depth,       8,
  684.                 SA_Type,        CUSTOMSCREEN,
  685.                 SA_DisplayID,   cmode,
  686.                 SA_ErrorCode,   (ULONG)&sa_error,
  687.             TAG_DONE);
  688.  
  689. #else
  690.             scr = OpenScreenTags( NULL,
  691.                 SA_Quiet,       TRUE,
  692.                 SA_Left,        0,
  693.                 SA_Top,         0,
  694.                 SA_Width,       w,
  695.                 SA_Height,      h,
  696.                 SA_Title,       (ULONG)smode,
  697.                 SA_Depth,       depth,
  698.                 SA_Type,        CUSTOMSCREEN,
  699.                 SA_DisplayID,   cmode,
  700.                 SA_BitMap,      (ULONG)(&bm),
  701.                 SA_ErrorCode,   (ULONG)&sa_error,
  702.             TAG_DONE);
  703. #endif
  704.             if (!scr) {
  705.                 printf("Can`t open screen: ");
  706.                 switch(sa_error) {
  707.                     case OSERR_NOMONITOR:
  708.                         printf("Monitor not available\n"); break;
  709.                     case OSERR_NOCHIPS:
  710.                         printf("Custom chips too old\n"); break;
  711.                     case OSERR_NOMEM:
  712.                         printf("Could not get enough memory\n"); break;
  713.                     case OSERR_NOCHIPMEM:
  714.                         printf("Could not get enough chip memory\n"); break;
  715.                     case OSERR_PUBNOTUNIQUE:
  716.                         printf("Public screen name not unique\n"); break;
  717.                     case OSERR_UNKNOWNMODE:
  718.                         printf("This mode is unknown\n"); break;
  719.                     case OSERR_TOODEEP:
  720.                         printf("Screen too deep to be displayed on this hardware\n"); break;
  721.                     case OSERR_ATTACHFAIL:
  722.                         printf("Illegal attachment for screens\n"); break;
  723.                     default:
  724.                         printf("Unknown error\n"); break;
  725.                 }
  726.                 exit(1);
  727.             }
  728.             if (scr->Width != w || scr->Height != h) {
  729.                 printf("Warning: Screen dimensions do not match requested dimensions\n");
  730.             }
  731.             if (win2) {
  732.                 CloseWindow(win2);
  733.                 win2 = NULL;
  734.             }
  735.             if (scr2) {
  736.                 CloseScreen(scr2);
  737.                 scr2 = NULL;
  738.             }
  739. #ifndef WARP3D
  740.             win = OpenWindowTags( NULL,
  741.                 WA_Left,        0,
  742.                 WA_Top,         0,
  743.                 WA_Width,       w,
  744.                 WA_Height,      h,
  745.                 WA_Flags,       WFLG_BORDERLESS|WFLG_SIMPLE_REFRESH|WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_REPORTMOUSE,
  746.                 WA_AutoAdjust,  TRUE,
  747.                 WA_IDCMP,       IDCMP_RAWKEY,
  748.                 WA_CustomScreen, (ULONG)scr,
  749.                 WA_SimpleRefresh, TRUE,
  750.                 TAG_DONE);
  751. #else
  752.         debug(("gr_set_mode: opening window\n"));
  753.             win = OpenWindowTags( NULL,
  754.                 WA_Left,        0,
  755.                 WA_Top,         0,
  756.                 WA_Width,       w,
  757.                 WA_Height,      h*2,
  758.                 WA_Flags,       WFLG_BORDERLESS|WFLG_SIMPLE_REFRESH|WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_REPORTMOUSE,
  759.                 WA_AutoAdjust,  TRUE,
  760.                 WA_IDCMP,       IDCMP_RAWKEY,
  761.                 WA_CustomScreen, (ULONG)scr,
  762.                 WA_SimpleRefresh, TRUE,
  763.                 TAG_DONE);
  764. #endif
  765.             if (!win) {
  766.                 if (scr) {
  767.                     CloseScreen(scr);
  768.                     scr = NULL;
  769.                 }
  770.                 if (win2) {
  771.                     CloseWindow(win2);
  772.                     win2 = NULL;
  773.                 }
  774.                 if (scr2) {
  775.                     CloseScreen(scr2);
  776.                     scr2 = NULL;
  777.                 }
  778.                 Error("Can`t open window (%d,%d)\n", w, h);
  779.                 exit(1);
  780.             }
  781.         } else {
  782.             scr = LockPubScreen(NULL);
  783.             win = OpenWindowTags( NULL,
  784.                 WA_Title,       (ULONG)"Amiga Descent",
  785.                 WA_InnerWidth,  w,
  786.                 WA_InnerHeight, h,
  787.                 WA_Borderless,  FALSE,
  788.                 WA_SizeGadget,  FALSE,
  789.                 WA_DragBar,     TRUE,
  790.                 WA_DepthGadget, TRUE,
  791.                 WA_CloseGadget, FALSE,
  792.                 WA_RMBTrap,     TRUE,
  793.                 WA_IDCMP,       IDCMP_RAWKEY,
  794.                 WA_Activate,    TRUE,
  795.                 WA_CustomScreen, (ULONG)scr,
  796.                 WA_SimpleRefresh, FALSE,
  797.                 TAG_DONE);
  798.             if (!win) {
  799.                  Error("Can`t open window\n");
  800.                  exit(1);
  801.             }
  802.         }
  803.  
  804.         if (scr->Width < w || scr->Height < h) {
  805.             Error("Selected video mode too small\n");
  806.             exit(0);
  807.         }
  808.  
  809. #else
  810.     if (!MyView) {
  811.         MyView = V3D_OpenViewTagList(ww,hh, 15L, opentags);
  812. #endif
  813.  
  814.         if (OffscreenBuffer) FreeVec(OffscreenBuffer);
  815.         OffscreenBuffer = AllocVec(w*h, MEMF_CLEAR);
  816.         if (!OffscreenBuffer) {
  817.             Error("No memory for offscreen buffer\n");
  818.             exit(0);
  819.         }
  820.         OffscreenH = h;
  821.         OffscreenW = w;
  822.         OffscreenSize = (h*w)/8;
  823.         if (compare_buffer) FreeVec(compare_buffer);
  824.         compare_buffer = AllocVec(w*h, MEMF_CLEAR);
  825.         if (!compare_buffer) {
  826.             printf("Error: No memory for compare_buffer\n");
  827.             exit(0);
  828.         }
  829.     }
  830.  
  831. #ifndef VIRGIN
  832.     if (scr && scr2) {
  833.         CloseWindow(win2);
  834.         if (wbmode) {
  835.             UnlockPubScreen(NULL, InfoScr);
  836.         } else {
  837.             CloseScreen(scr2);
  838.         }
  839.     }
  840.  
  841.     if (win && wbmode == 0) {
  842.         SetPointer(win, PointerData, 16, 16, 1, 1);
  843.     }
  844. #else
  845.     if (MyView && MyView2) {
  846.         VirgeCleanupTextureCache();
  847.         V3D_CloseView(MyView2);
  848.         MyView2=NULL;
  849.     }
  850.  
  851.     MyViewMsgPort = V3D_CreateEventPort(MyView, IDCMP_RAWKEY);
  852. #endif
  853.  
  854.     gr_palette_clear();
  855.     grd_curscreen->sc_w = w;
  856.     grd_curscreen->sc_h = h;
  857.     grd_curscreen->sc_aspect = fixdiv(grd_curscreen->sc_w*3,grd_curscreen->sc_h*4);
  858.     grd_curscreen->sc_canvas.cv_bitmap.bm_x = 0;
  859.     grd_curscreen->sc_canvas.cv_bitmap.bm_y = 0;
  860.     grd_curscreen->sc_canvas.cv_bitmap.bm_type = BM_LINEAR;
  861.     grd_curscreen->sc_canvas.cv_bitmap.bm_w = w;
  862.     grd_curscreen->sc_canvas.cv_bitmap.bm_h = h;
  863.     grd_curscreen->sc_canvas.cv_bitmap.bm_rowsize = w;
  864.  
  865.     if (w>600) {
  866.         wscale = (w+1)/w;
  867.         hscale = (h+1)/h;
  868.     } else {
  869.         wscale = 1.0;
  870.         hscale = 1.0;
  871.     }
  872.  
  873.     debug(("gr_set_mode: bitmap is %ld×%ld\n", w, h));
  874.  
  875. #if !defined(VIRGIN) && !defined(WARP3D)
  876.     if (cgx_direct == 1) {
  877.         Forbid();
  878.         grd_curscreen->sc_canvas.cv_bitmap.bm_Handle =
  879.                           (void *)LockBitMapTags(win->RPort->BitMap,
  880.                             LBMI_BASEADDRESS,   (ULONG)(&adr),
  881.                             TAG_DONE);
  882.         UnLockBitMap((APTR)(grd_curscreen->sc_canvas.cv_bitmap.bm_Handle));
  883.         Permit();
  884.         grd_curscreen->sc_canvas.cv_bitmap.bm_data = (ubyte *)adr;
  885.     } else {
  886. #endif
  887.         grd_curscreen->sc_canvas.cv_bitmap.bm_data = (ubyte *)OffscreenBuffer;
  888. #if !defined(VIRIGN) && !defined(WARP3D)
  889.     }
  890. #endif
  891.  
  892.     gr_set_current_canvas(NULL);
  893. #ifdef VIRGIN
  894.     VirgeInitTextureCache();
  895.     VirgeSetupBuffers();
  896. #endif
  897.  
  898.     gr_pixfmt = GetCyberMapAttr(scr->RastPort.BitMap, CYBRMATTR_PIXFMT);
  899.  
  900.     debug(("gr_set_mode: done\n"));
  901.  
  902.     return 0;
  903. #endif
  904. }
  905.  
  906. extern void gr_build_mac_gamma(double correction);
  907. extern double gamma_corrections[9];
  908. extern ubyte gr_palette_gamma;
  909.  
  910. int gr_init(int mode)
  911. {
  912.     int retcode;
  913.  
  914.     debug(("gr_init\n"));
  915.  
  916.     // Only do this function once!
  917.     if (gr_installed==1)
  918.         return 1;
  919.  
  920.     HideInfoWindow();
  921.  
  922.     // Save the current palette, and fade it out to black.
  923.  
  924.     MALLOC( grd_curscreen,grs_screen,1 );
  925.     memset( grd_curscreen, 0, sizeof(grs_screen));
  926.     
  927. // initialize the macintosh window that we will use -- including picking the
  928. // monitor
  929.  
  930.     // Set the mode.
  931.     if ((retcode=gr_set_mode(mode)))
  932.         return retcode;
  933.  
  934. //JOHNgr_disable_default_palette_loading();
  935.  
  936.     gr_build_mac_gamma(gamma_corrections[gr_palette_gamma]);
  937.  
  938.     // Set all the screen, canvas, and bitmap variables that
  939.     // aren't set by the gr_set_mode call:
  940.     grd_curscreen->sc_canvas.cv_color = 0;
  941.     grd_curscreen->sc_canvas.cv_drawmode = 0;
  942.     grd_curscreen->sc_canvas.cv_font = NULL;
  943.     grd_curscreen->sc_canvas.cv_font_fg_color = 0;
  944.     grd_curscreen->sc_canvas.cv_font_bg_color = 0;
  945.     gr_set_current_canvas( &grd_curscreen->sc_canvas );
  946.  
  947.     // Set flags indicating that this is installed.
  948.     gr_installed = 1;
  949.     atexit(gr_close);
  950.  
  951.     return 0;
  952. }
  953.  
  954. int gr_check_mode(int mode) {
  955.     return 0; // *shrug*
  956. }
  957.  
  958. void gr_wlpa(void) {
  959. #ifndef VIRGIN
  960.     //  Kludge to replace WriteLUTPixelArray
  961.  
  962.     APTR handle;
  963.     int x,y;
  964.     ULONG pixfmt;
  965.     UWORD *adr, *oadr;
  966.     UBYTE *offscr = OffscreenBuffer;
  967.     ULONG width;
  968.  
  969.     Forbid();
  970.     handle = LockBitMapTags(win->RPort->BitMap,
  971.                     LBMI_BASEADDRESS,   (ULONG)(&adr),
  972.                     LBMI_BYTESPERROW,   (ULONG)(&width),
  973.                     TAG_DONE);
  974.  
  975.  
  976.     adr = (UWORD *)(((UBYTE *)adr) +
  977.             (width * (win->TopEdge + win->BorderTop)) +
  978.             (win->LeftEdge + win->BorderLeft));
  979.  
  980.     for (y = OffscreenH; y > 0; y--) {
  981.         oadr = adr;
  982.         for (x = OffscreenW; x > 0; x--) {
  983.             *adr++ = gr_bitvalues[*offscr++];
  984.         }
  985.         adr = (UWORD *)((UBYTE *)oadr + width); // put to next line
  986.     }
  987.  
  988.     UnLockBitMap(handle);
  989.     Permit();
  990. #endif
  991. }
  992.  
  993. void gr_mouse_setimage(int image);
  994.  
  995. void gr_mouse_show(void)
  996. {
  997. #ifndef VIRGIN
  998. //    gr_mouse_setimage(1);
  999.     SetPointer(win, EditorPointer, 11, 16, 0, 0);
  1000.     gr_mouse_reported = 1;
  1001. #endif
  1002. }
  1003.  
  1004. void gr_mouse_hide(void)
  1005. {
  1006. #ifndef VIRGIN
  1007. //    gr_mouse_setimage(0);
  1008.     SetPointer(win, PointerData, 11, 16, 0, 0);
  1009.     gr_mouse_reported = 0;
  1010. #endif
  1011. }
  1012.  
  1013. #ifdef EDITOR
  1014. extern char ui_mouse_pointer[];
  1015. #endif
  1016.  
  1017. #define PTR_W 11
  1018. #define PTR_H 19
  1019.  
  1020. void gr_mouse_setimage(int image)
  1021. {
  1022. #ifdef EDITOR
  1023.     int j, i;
  1024.     UWORD first, second;
  1025.     int b;
  1026.     UWORD *here;
  1027. #ifndef VIRGIN
  1028.     if (image == 0) {
  1029.         for (i = 0; i < 256; i++) PointerData[i] = 0;
  1030.         SetPointer(win, PointerData, 16, 16, 1, 1);
  1031.     } else {
  1032.         here = PointerData + 2;
  1033.         PointerData[0] = 0;
  1034.         PointerData[1] = 0;
  1035.         for (i = 0; i < PTR_H; i++) {
  1036.             first = 0;
  1037.             second = 0;
  1038.             b = 1;
  1039.             for (j = PTR_W; j > 0; j--) {
  1040.                 switch (ui_mouse_pointer[i * PTR_W +j]) {
  1041.                     case '1': first &= b;
  1042.                             break;
  1043.                     case '2': second &= b;
  1044.                             break;
  1045.                     case '4': first &= b;
  1046.                             second &= b;
  1047.                             break;
  1048.                 }
  1049.                 b = b << 1;
  1050.             }
  1051.             *here ++ = first;
  1052.             *here ++ = second;
  1053.         }
  1054.         *here++ = 0;
  1055.         *here ++ = 0;
  1056.  
  1057.         SetPointer(win, PointerData, PTR_H, PTR_W, 1, 1);
  1058.     }
  1059. #endif
  1060. #endif
  1061. }
  1062.